using Microsoft.Extensions.Diagnostics.HealthChecks;
using WeatherSystem.API.Services;

namespace WeatherSystem.API.HealthChecks
{
    /// <summary>
    /// 自定义健康检查
    /// </summary>
    public class CustomHealthCheck : IHealthCheck
    {
        private readonly IErrorRecoveryService _errorRecoveryService;
        private readonly ILogger<CustomHealthCheck> _logger;

        public CustomHealthCheck(IErrorRecoveryService errorRecoveryService, ILogger<CustomHealthCheck> logger)
        {
            _errorRecoveryService = errorRecoveryService;
            _logger = logger;
        }

        public async Task<HealthCheckResult> CheckHealthAsync(
            HealthCheckContext context,
            CancellationToken cancellationToken = default)
        {
            try
            {
                var systemHealth = await _errorRecoveryService.GetSystemHealthAsync();
                
                var data = new Dictionary<string, object>
                {
                    ["LastUpdated"] = systemHealth.LastUpdated,
                    ["ComponentCount"] = systemHealth.Components.Count,
                    ["Issues"] = systemHealth.Issues
                };

                // 添加组件详细信息
                foreach (var component in systemHealth.Components)
                {
                    data[$"Component_{component.Key}"] = new
                    {
                        component.Value.Status,
                        component.Value.LastCheck,
                        component.Value.ResponseTime,
                        component.Value.Description
                    };
                }

                return systemHealth.Status switch
                {
                    "Healthy" => HealthCheckResult.Healthy("系统健康", data),
                    "Degraded" => HealthCheckResult.Degraded($"系统部分降级: {string.Join(", ", systemHealth.Issues)}", data: data),
                    "Unhealthy" => HealthCheckResult.Unhealthy($"系统不健康: {string.Join(", ", systemHealth.Issues)}", data: data),
                    _ => HealthCheckResult.Unhealthy("未知系统状态", data: data)
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "健康检查执行失败");
                return HealthCheckResult.Unhealthy("健康检查执行失败", ex);
            }
        }
    }

    /// <summary>
    /// 数据库健康检查
    /// </summary>
    public class DatabaseHealthCheck : IHealthCheck
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly ILogger<DatabaseHealthCheck> _logger;

        public DatabaseHealthCheck(IServiceProvider serviceProvider, ILogger<DatabaseHealthCheck> logger)
        {
            _serviceProvider = serviceProvider;
            _logger = logger;
        }

        public async Task<HealthCheckResult> CheckHealthAsync(
            HealthCheckContext context,
            CancellationToken cancellationToken = default)
        {
            try
            {
                using var scope = _serviceProvider.CreateScope();
                var dbContext = scope.ServiceProvider.GetRequiredService<Data.WeatherDbContext>();
                
                var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                
                // 执行简单的数据库查询
                var canConnect = await dbContext.Database.CanConnectAsync(cancellationToken);
                
                stopwatch.Stop();

                var data = new Dictionary<string, object>
                {
                    ["ResponseTime"] = stopwatch.ElapsedMilliseconds,
                    ["CanConnect"] = canConnect,
                    ["CheckedAt"] = DateTime.UtcNow
                };

                if (canConnect)
                {
                    return stopwatch.ElapsedMilliseconds < 1000
                        ? HealthCheckResult.Healthy($"数据库连接正常，响应时间: {stopwatch.ElapsedMilliseconds}ms", data)
                        : HealthCheckResult.Degraded($"数据库连接缓慢，响应时间: {stopwatch.ElapsedMilliseconds}ms", data: data);
                }
                else
                {
                    return HealthCheckResult.Unhealthy("无法连接到数据库", data: data);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "数据库健康检查失败");
                return HealthCheckResult.Unhealthy("数据库健康检查异常", ex);
            }
        }
    }

    /// <summary>
    /// 外部服务健康检查
    /// </summary>
    public class ExternalServiceHealthCheck : IHealthCheck
    {
        private readonly HttpClient _httpClient;
        private readonly IConfiguration _configuration;
        private readonly ILogger<ExternalServiceHealthCheck> _logger;

        public ExternalServiceHealthCheck(
            HttpClient httpClient, 
            IConfiguration configuration,
            ILogger<ExternalServiceHealthCheck> logger)
        {
            _httpClient = httpClient;
            _configuration = configuration;
            _logger = logger;
        }

        public async Task<HealthCheckResult> CheckHealthAsync(
            HealthCheckContext context,
            CancellationToken cancellationToken = default)
        {
            try
            {
                var weatherApiUrl = "https://api.openweathermap.org/data/2.5/weather";
                var apiKey = Environment.GetEnvironmentVariable("OPENWEATHERMAP_API_KEY");
                
                if (string.IsNullOrEmpty(apiKey))
                {
                    return HealthCheckResult.Degraded("外部天气API密钥未配置", 
                        data: new Dictionary<string, object> { ["ApiKey"] = "Not configured" });
                }

                var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                
                // 测试API连接（使用示例城市ID）
                var testUrl = $"{weatherApiUrl}?id=2172797&appid={apiKey}";
                using var response = await _httpClient.GetAsync(testUrl, cancellationToken);
                
                stopwatch.Stop();

                var data = new Dictionary<string, object>
                {
                    ["ResponseTime"] = stopwatch.ElapsedMilliseconds,
                    ["StatusCode"] = (int)response.StatusCode,
                    ["IsSuccess"] = response.IsSuccessStatusCode,
                    ["CheckedAt"] = DateTime.UtcNow
                };

                if (response.IsSuccessStatusCode)
                {
                    return stopwatch.ElapsedMilliseconds < 5000
                        ? HealthCheckResult.Healthy($"外部天气API正常，响应时间: {stopwatch.ElapsedMilliseconds}ms", data)
                        : HealthCheckResult.Degraded($"外部天气API响应缓慢，响应时间: {stopwatch.ElapsedMilliseconds}ms", data: data);
                }
                else
                {
                    return HealthCheckResult.Unhealthy($"外部天气API返回错误状态码: {response.StatusCode}", data: data);
                }
            }
            catch (TaskCanceledException) when (cancellationToken.IsCancellationRequested)
            {
                return HealthCheckResult.Unhealthy("外部天气API健康检查被取消");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "外部天气API健康检查失败");
                return HealthCheckResult.Unhealthy("外部天气API健康检查异常", ex);
            }
        }
    }
}